package com.xtaller.sdboot.controller;

import com.alibaba.fastjson.JSONObject;
import com.xtaller.sdboot.entity.*;
import com.xtaller.sdboot.service.*;
import com.xtaller.sdboot.vo.AccountVO;
import com.xtaller.sdboot.core.R;
import com.xtaller.sdboot.core.Status;
import com.xtaller.sdboot.utils.annotation.Permission;
import com.xtaller.sdboot.core.base.BaseController;
import com.xtaller.sdboot.core.base.BaseEntity;
import com.xtaller.sdboot.utils.helper.JsonHelper;
import com.xtaller.sdboot.utils.helper.MD5Helper;
import com.xtaller.sdboot.utils.helper.Sha1Helper;
import com.xtaller.sdboot.utils.helper.StrHelper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.var;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.io.Serializable;

/** 
* 代码生成 
* @author: Taller  
* @date: 2020-02-22 00:25:29
* @Description: 登录账户控制器 
*/ 
@Api(tags = "登录账户控制器") 
@RestController 
@RequestMapping("/v1/iam/account") 
public class IamAccountController extends BaseController<IamAccount> {
    @Autowired private IamUserService userService;
    @Autowired private IamAccountService accountService;
    @Autowired private IamApplicationService applicationService;
    @Autowired private IamUserApplicationService userApplicationService;
    @Autowired private IamRoleService roleService;
    @Autowired private IamUserRoleService userRoleService;

    @ApiOperation("表格")
    @Permission(authorities = "iam:account:data:list")
    @Override
    public Object getByPage(HttpServletRequest request) throws Exception {
        return super.getByPage(request);
    }

    @ApiOperation("修改")
    @Permission(authorities = "iam:account:opt:update")
    @Override
    public Object updateEntity(@PathVariable("id") Serializable id, @Valid @RequestBody IamAccount entity, HttpServletRequest request) throws Exception {
        return super.updateEntity(id, entity, request);
    }

    @ApiOperation("删除")
    @Permission(authorities = "iam:account:opt:delete")
    @Override
    public Object deleteEntity(@PathVariable("id") Serializable id, HttpServletRequest request) throws Exception {
        return super.deleteEntity(id, request);
    }

    @Override
    protected String beforeUpdate(BaseEntity entity) throws Exception {
        var model = (IamAccount) entity;
        var old = accountService.get(entity.getId());
        if(!model.getAuthAccount().equals(old.getAuthAccount())){
            return "禁止修改电话号码";
        }
        return super.beforeUpdate(entity);
    }

    @Override
    protected String beforeCreate(BaseEntity entity) throws Exception {
        var ia = (IamAccount) entity;
        // 判断是否创建了登录账户
        var accountQw = new QueryWrapper<IamAccount>();
        accountQw.lambda()
                .eq(IamAccount::getAuthAccount, ia.getAuthAccount())
                .eq(IamAccount::getUserType, "iam");
        var account = accountService.get(accountQw);
        if(account != null){
            return "手机号已经注册";
        }

        // 判断用户手机号是否在iam_user中
        var userQw = new QueryWrapper<IamUser>();
        userQw.lambda().eq(IamUser::getMobile, ia.getAuthAccount());
        var user = userService.get(userQw);
        if(user == null){
            // 创建用户
            var uid = StrHelper.newUuid();
            var userModel = JsonHelper.o2m(ia, IamUser.class);
            userModel.setMobile(ia.getAuthAccount());
            userModel.setId(uid);
            if(userService.create(userModel)){
                user = userModel;
            }
        }

        // 写入IamAccount
        ia.setUserId(user.getId());
        ia.setUserType("iam");
        ia.setAuthType("pwd");
        // todo 这里可使用密码发送至手机
        // 登录密码
        var pwd = "123456";
        var salt = StrHelper.newRandomNum(6);
        var npwd = Sha1Helper.shaEncode(pwd);
        if(pwd.length() == 0){
            return "无法生成密码";
        }
        npwd = MD5Helper.encode(npwd + salt);
        ia.setAuthSecret(npwd);
        ia.setAuthSalt(salt);

        return super.beforeCreate(ia);
    }

    @Override
    protected String afterCreated(BaseEntity entity) throws Exception {
        return super.afterCreated(entity);
    }

    @Override
    protected String afterDelete(BaseEntity entity) throws Exception {
        // 检查iam_user_application 如果存在 全部清空该用户的信息
        var qw = new QueryWrapper<IamUserApplication>();
        qw.lambda().eq(IamUserApplication::getUserId, entity.getId());
        userApplicationService.delete(qw);
        return super.afterDelete(entity);
    }

    /**
     * 创建后台登录用户
     * */
    @PostMapping("/platform")
    @ApiOperation("创建后台登录用户")
    @Permission(authorities = "iam:account:opt:create")
    public Object createIamAccount(@Valid @RequestBody AccountVO vo, HttpServletRequest request){
        var result = createUser(vo, null);

        if(result.getBoolean("success")){
            return R.ok(result.getString("message"));
        }
        return R.error(Status.FAIL_EXCEPTION, result.getString("message"));
    }

    @PostMapping("/application")
    @ApiOperation("创建应用登录用户")
    @Permission(authorities = "iam:account:app:opt:create")
    public Object createIamApplicationAccount(@Valid @RequestBody AccountVO vo, HttpServletRequest request){
        if(applicationId.get() == null){
            return R.error(Status.FAIL_INVALID_PARAM, "应用数据异常");
        }
        var ua = new IamUserApplication();
        ua.setAppId(applicationId.get());

        // 判断是否创建了登录账户
        var accountQw = new QueryWrapper<IamAccount>();
        accountQw.lambda()
                .eq(IamAccount::getAuthAccount, vo.getMobile())
                .eq(IamAccount::getUserType, "iam");
        var account = accountService.get(accountQw);
        if(account != null){
            // 判断是否在应用中
            var uaQw = new QueryWrapper<IamUserApplication>();
            uaQw.lambda()
                    .eq(IamUserApplication::getAppId, applicationId.get())
                    .eq(IamUserApplication::getUserId, account.getUserId());
            var uas = userApplicationService.getList(uaQw);
            if(uas.size() > 0){
                return R.error(Status.FAIL_VALIDATION, "当前用户已创建");
            }else {
                ua.setUserId(account.getUserId());
                userApplicationService.create(ua);
                setRole(account.getUserId());
                return R.ok("用户创建成功");
            }
        }else{
            var result = createUser(vo, ua);
            if(result.getBoolean("success")){
                return R.ok(result.getString("message"));
            }
            return R.error(Status.FAIL_EXCEPTION, result.getString("message"));
        }

    }

    @PutMapping("/application/{id}")
    @ApiOperation("修改应用登录用户")
    @Permission(authorities = "iam:account:app:opt:update")
    public Object updateApplicationAccount(@PathVariable("id") String id, @Valid @RequestBody AccountVO vo, HttpServletRequest request){
        if(applicationId.get() == null){
            return R.error(Status.FAIL_INVALID_PARAM, "应用数据异常");
        }
        var ua = new IamUserApplication();
        ua.setAppId((String) applicationId.get());
        var result = createUser(vo, ua);

        if(result.getBoolean("success")){
            return R.ok(result.getString("message"));
        }
        return R.error(Status.FAIL_EXCEPTION, result.getString("message"));
    }

    @DeleteMapping("/application/{id}")
    @ApiOperation("删除应用登录用户")
    @Permission(authorities = "iam:account:app:opt:delete")
    public Object deleteAppAccount(@PathVariable("id") String id, HttpServletRequest request){
        if(applicationId.get() == null){
            return R.error(Status.FAIL_INVALID_PARAM, "应用数据异常");
        }
        var account = accountService.get(id);
        if(account == null){
            return R.error(Status.FAIL_NOT_FOUND, "应用数据Id异常");
        }
        if(accountService.delete(id)){
            // 移除系统关系
            var qw = new QueryWrapper<IamUserApplication>();
            qw.lambda()
                    .eq(IamUserApplication::getUserId, account.getUserId())
                    .eq(IamUserApplication::getAppId, applicationId.get());
            userApplicationService.delete(qw);
            // 移除角色
            var qw2 = new QueryWrapper<IamUserRole>();
            qw2.lambda()
                    .eq(IamUserRole::getAppId, applicationId.get())
                    .eq(IamUserRole::getUserId, account.getUserId());
            userRoleService.delete(qw2);
            return R.ok("删除成功");
        }

        return R.error(Status.FAIL_EXCEPTION, "删除异常");
    }


    private JSONObject createUser(AccountVO vo, IamUserApplication ua){
        // 检查应用
        if(ua != null){
            if(applicationService.get(ua.getAppId()) == null){
                return JsonHelper.create("success", false)
                        .put("message", "应用数据异常");
            }
        }
        // 判断是否创建了登录账户
        var accountQw = new QueryWrapper<IamAccount>();
        accountQw.lambda()
                .eq(IamAccount::getAuthAccount, vo.getMobile())
                .eq(IamAccount::getUserType, "iam");
        var account = accountService.get(accountQw);
        if(account != null){
            return JsonHelper.create("success", false)
                        .put("message", "手机号已经注册");
        }
        // 判断用户手机号是否在iam_user中
        var userQw = new QueryWrapper<IamUser>();
        userQw.lambda().eq(IamUser::getMobile, vo.getMobile());
        var user = userService.get(userQw);
        if(user == null){
            // 创建用户
            var uid = StrHelper.newUuid();
            var userModel = JsonHelper.o2m(vo, IamUser.class);
            userModel.setId(uid);
            if(userService.create(userModel)){
                user = userModel;
            }
        }
        // 写入IamAccount
        account = new IamAccount();
        account.setUserId(user.getId());
        account.setUserType("iam");
        account.setAuthType("pwd");
        account.setAuthAccount(vo.getMobile());
        account.setRealName(vo.getRealName());
        account.setGender(vo.getGender());
        account.setEmail(vo.getEmail());

        // todo 这里可使用密码发送至手机
        // 登录密码
        var pwd = "123456";
        var salt = StrHelper.newRandomNum(6);
        var npwd = Sha1Helper.shaEncode(pwd);
        if(pwd.length() == 0){
            return JsonHelper.create("success", false)
                    .put("message", "无法生成密码");
        }
        npwd = MD5Helper.encode(npwd + salt);
        account.setAuthSecret(npwd);
        account.setAuthSalt(salt);

        if(accountService.create(account)){
            if(ua != null){
                ua.setUserId(user.getId());
                userApplicationService.create(ua);
                setRole(user.getId());
            }
            return JsonHelper.create("success", true)
                    .put("message", "用户创建成功");
        }
        return JsonHelper.create("success", false)
                .put("message", "用户创建失败");
    }

    private void setRole(String userId){
        // 检查是否有默认角色
        var qw = new QueryWrapper<IamRole>();
        qw.lambda().eq(IamRole::getAppId, applicationId.get())
                .eq(IamRole::getIsDefault, 1);
        var roles = roleService.getList(qw);
        if(roles.size() > 0){
            var role = roles.get(0);
            var ur = new IamUserRole();
            ur.setAppId(applicationId.get());
            ur.setUserId(userId);
            ur.setRoleId(role.getId());
            userRoleService.model(ur);
        }
    }
}
